#ifndef __WIZ_TIMER_PAUSEABLE_HPP__SHANHAOBO_19800429__
#define __WIZ_TIMER_PAUSEABLE_HPP__SHANHAOBO_19800429__

#include "../Base/Type/WizBaseType.hpp"
#include "./WizLock.hpp"

#include "./WizTimer.hpp"

namespace Wiz
{
    namespace Timer
    {
        namespace PauseAble
        {
            ////////////////////////////////////////////////////////////////////////
            class WIZ_EXPORT Type
            {
                ::Wiz::Real32::Type m_Start;
                ::Wiz::Real32::Type m_PauseStart;
                ::Wiz::Bool::Type   m_Pause;
                ::Wiz::Lock::Type   m_PauseLock;
            public:
                Type() : m_Pause(::Wiz::Bool::False){}
                ~Type(){}
            public:
                ::Wiz::Void::Type Start()
                {
                    this->Restart();
                }
                ::Wiz::Void::Type Restart()
                {
                    ::Wiz::ScopedLock::Type l(m_PauseLock);
                    m_Start = ::Wiz::Timer::Now();
                    m_Pause =  ::Wiz::Bool::False;
                }

                ::Wiz::Void::Type Pause()
                {
                    ::Wiz::ScopedLock::Type l(m_PauseLock);
                    if (this->m_Pause == ::Wiz::Bool::True)
                    {
                        return;
                    }
                    this->m_Pause = ::Wiz::Bool::True;

                    this->m_PauseStart = ::Wiz::Timer::Now();
                }

                ::Wiz::Void::Type Continue()
                {
                    ::Wiz::ScopedLock::Type l(m_PauseLock);
                    if (this->m_Pause == ::Wiz::Bool::False)
                    {
                        return;
                    }
                    this->m_Pause = ::Wiz::Bool::False;

                    this->m_Start += ::Wiz::Timer::Now() - this->m_PauseStart;
                }

                ::Wiz::Real32::Type Elapsed()
                {
                    return ::Wiz::Timer::Now() - this->m_Start;
                }
            };
            WIZ_DECLARE(::Wiz::Timer::PauseAble::Type);
            ///////////////////////////////////////////////////////////////////////

            ///////////////////////////////////////////////////////////////////////
            namespace MS
            {
                class WIZ_EXPORT Type
                {
                    ::Wiz::UInt32::Type m_Start;
                    ::Wiz::UInt32::Type m_PauseStart;
                    ::Wiz::Bool::Type   m_Pause;
                    ::Wiz::Lock::Type   m_PauseLock;
                public:
                    Type() : m_Pause(::Wiz::Bool::False){}
                    ~Type(){}
                public:
                    ::Wiz::Void::Type Start()
                    {
                        this->Restart();
                    }
                    ::Wiz::Void::Type Restart()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        m_Start = ::Wiz::Timer::NowMS();
                        m_Pause =  ::Wiz::Bool::False;
                    }

                    ::Wiz::Void::Type Pause()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        if (this->m_Pause == ::Wiz::Bool::True)
                        {
                            return;
                        }
                        this->m_Pause = ::Wiz::Bool::True;

                        this->m_PauseStart = ::Wiz::Timer::NowMS();
                    }

                    ::Wiz::Void::Type Continue()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        if (this->m_Pause == ::Wiz::Bool::False)
                        {
                            return;
                        }
                        this->m_Pause = ::Wiz::Bool::False;

                        this->m_Start += ::Wiz::Timer::NowMS() - this->m_PauseStart;
                    }

                    ::Wiz::UInt32::Type Elapsed()
                    {
                        return ::Wiz::Timer::NowMS() - this->m_Start;
                    }
                };
                WIZ_DECLARE(::Wiz::Timer::PauseAble::MS::Type);
            }; /// end of namespace MS
            ///////////////////////////////////////////////////////////////////////

            ///////////////////////////////////////////////////////////////////////
            namespace US
            {
                class WIZ_EXPORT Type
                {
                    ::Wiz::UInt64::Type m_Start;
                    ::Wiz::UInt64::Type m_PauseStart;
                    ::Wiz::Bool::Type   m_Pause;
                    ::Wiz::Lock::Type   m_PauseLock;
                public:
                    Type() : m_Pause(::Wiz::Bool::False){}
                    ~Type(){}
                public:
                    ::Wiz::Void::Type Start()
                    {
                        this->Restart();
                    }
                    ::Wiz::Void::Type Restart()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        m_Start = ::Wiz::Timer::NowUS();
                        m_Pause =  ::Wiz::Bool::False;
                    }

                    ::Wiz::Void::Type Pause()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        if (this->m_Pause == ::Wiz::Bool::True)
                        {
                            return;
                        }
                        this->m_Pause = ::Wiz::Bool::True;

                        this->m_PauseStart = ::Wiz::Timer::NowUS();
                    }

                    ::Wiz::Void::Type Continue()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        if (this->m_Pause == ::Wiz::Bool::False)
                        {
                            return;
                        }
                        this->m_Pause = ::Wiz::Bool::False;

                        this->m_Start += ::Wiz::Timer::NowUS() - this->m_PauseStart;
                    }

                    ::Wiz::UInt64::Type Elapsed()
                    {
                        return ::Wiz::Timer::NowUS() - this->m_Start;
                    }
                };
                WIZ_DECLARE(::Wiz::Timer::PauseAble::US::Type);
            }; /// end of namespace US
            ///////////////////////////////////////////////////////////////////////

            ///////////////////////////////////////////////////////////////////////
            namespace NS
            {
                class WIZ_EXPORT Type
                {
                    ::Wiz::UInt64::Type m_Start;
                    ::Wiz::UInt64::Type m_PauseStart;
                    ::Wiz::Bool::Type   m_Pause;
                    ::Wiz::Lock::Type   m_PauseLock;
                public:
                    Type() : m_Pause(::Wiz::Bool::False){}
                    ~Type(){}
                public:
                    ::Wiz::Void::Type Start()
                    {
                        this->Restart();
                    }
                    ::Wiz::Void::Type Restart()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        m_Start = ::Wiz::Timer::NowNS();
                        m_Pause =  ::Wiz::Bool::False;
                    }

                    ::Wiz::Void::Type Pause()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        if (this->m_Pause == ::Wiz::Bool::True)
                        {
                            return;
                        }
                        this->m_Pause = ::Wiz::Bool::True;

                        this->m_PauseStart = ::Wiz::Timer::NowNS();
                    }

                    ::Wiz::Void::Type Continue()
                    {
                        ::Wiz::ScopedLock::Type l(m_PauseLock);
                        if (this->m_Pause == ::Wiz::Bool::False)
                        {
                            return;
                        }
                        this->m_Pause = ::Wiz::Bool::False;

                        this->m_Start += ::Wiz::Timer::NowNS() - this->m_PauseStart;
                    }

                    ::Wiz::UInt64::Type Elapsed()
                    {
                        return ::Wiz::Timer::NowNS() - this->m_Start;
                    }
                };
                WIZ_DECLARE(::Wiz::Timer::PauseAble::NS::Type);
            }; /// end of namespace NS
            ///////////////////////////////////////////////////////////////////////
        } /// end of namespace PauseAble
    } /// end of namespace Timer
} /// end of namespace Wiz

#endif /*__WIZ_TIMER_PAUSEABLE_HPP__SHANHAOBO_19800429__*/
